/* eslint-disable no-undef */

import Canvas2Image from 'canvas2image'
import html2canvas from 'html2canvas'
// import gltfFile from "../../../models3D/d1.gltf"
// 测量类
import HandleMeasure from './measure'
// 地质开挖
import geologicalExcavation from './geologicalExcavation'
// 钻孔
import TurnHole from './turnHole';
// 根据数据绘制钻孔
import BatchTurnHole from './batchTurnHole';
// 绘制光柱
import LlightColumn from './lightColumn'
// 工具箱
import ToolsFactory from './toolsFactory'
// 绘制定位标注
import PositioningLabels from './positioningLabels'
// 绘线
import DrawLine from './drawLine'
// 绘制剖面
import DrawProfile from './drawProfile'
// 绘制平面
import DrawPlane from './drawPlane'
// 
import Add3DTileset from './add3DTileset'

import DxTiles from './dxTiles'

var dxCommonFun = function (params) {
  var DxCommonUtils = {
    // 测量类
    handleMeasure: HandleMeasure,
    handleTurnHole: TurnHole, // 地质打孔，
    handleGeologicalExcavation: geologicalExcavation, // 地质开挖
    // 类形式
    dxTiles: null,
    DxTiles: DxTiles,
    handleAdd3DTileset: new Add3DTileset(), // 
    handleDrawLine: new DrawLine(), // 绘线
    handleBatchTurnHole: new BatchTurnHole(), // 根据数据绘制钻孔
    handleDrawProfile: new DrawProfile(), // 根据数据绘制剖面
    handleDrawPlane: new DrawPlane(), // 绘制平面
    lightColumn: new LlightColumn, // 绘制光柱
    toolsList: new ToolsFactory(), // 工具箱
    positioningLabels: new PositioningLabels(),  // 绘制定位标注label（文字加图片）
    /* 获取camera中心点坐标 */
    getCenterPosition: function () {
      var result = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2))
      var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result)
      var lon = curPosition.longitude * 180 / Math.PI
      var lat = curPosition.latitude * 180 / Math.PI
      var height = this.getHeight()
      return { lon: lon, lat: lat, height: height.toFixed(3) }
    },
    // 获取海拔
    getHeight: function () {
      if (viewer) {
        var scene = viewer.scene
        var ellipsoid = scene.globe.ellipsoid
        var height = ellipsoid.cartesianToCartographic(viewer.camera.position).height
        return height
        // // 获取当前镜头位置的笛卡尔坐标
        // let cameraPos = viewer.camera.position;
        // // 获取当前坐标系标准
        // let ellipsoid = viewer.scene.globe.ellipsoid;
        // // 根据坐标系标准，将笛卡尔坐标转换为地理坐标
        // let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
        // // 获取镜头的高度
        // let height = cartographic.height;
      }
    },
    tools: {
      // 切近地面
      handleZoomAdd: function () {
        const height = DxCommonUtils.getHeight()
        // viewer.camera.zoomIn(height / 3);
        const positons = DxCommonUtils.getCenterPosition()
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(positons.lon, positons.lat, height / 1.6),
          duration: 1.0
        })
      },
      // 远离地面
      handleZoomMinus: function () {
        const height = DxCommonUtils.getHeight()
        // viewer.camera.zoomOut(height * 1.2);
        const positons = DxCommonUtils.getCenterPosition()
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(positons.lon, positons.lat, height * 1.8),
          duration: 1.0
        })
      },
      // 相机飞入
      handleAngleView() {
        // viewer.camera.flyTo({
        //   destination: Cesium.Cartesian3.fromDegrees(108.960428, 34.163736, 20000),
        //   duration: 1.0
        // })
        DxCommonUtils.cameraFlyTo({
          x: 108.960428,
          y: 34.163736,
          z: 20000
        })
      },
      // 指北
      handleRefersToNorth() {
        var direction = viewer.camera._direction;
        var x = Cesium.Math.toDegrees(direction.x);
        var y = Cesium.Math.toDegrees(direction.y);
        var z = Cesium.Math.toDegrees(direction.z);

        var rectangle = viewer.camera.computeViewRectangle();
        var west = rectangle.west / Math.PI * 180;
        var north = rectangle.north / Math.PI * 180;
        var east = rectangle.east / Math.PI * 180;
        var south = rectangle.south / Math.PI * 180;
        var centerx = (west + east) / 2;
        var cnetery = (north + south) / 2;
        var h = DxCommonUtils.getHeight()
        DxCommonUtils.cameraFlyTo({
          x: centerx,
          y: cnetery,
          z: h,
          heading: 0,
          pitch: -90,
          roll: -9.5
        })
      },
      // 截屏
      handleScreenshots() {
        var opts = {

          backgroundColor: null,
          dpi: 30000,
          foreignObjectRendering: true, // 是否在浏览器支持的情况下使用ForeignObject渲染
          useCORS: true, // 是否尝试使用CORS从服务器加载图像
          async: false // 是否异步解析和呈现元素
        }
        html2canvas(document.getElementById('cesiumContainer'), opts)// 传入你想生成图片的dom
          .then(
            function (canvas) {
              // 【重要】关闭抗锯齿
              const context = canvas.getContext('2d')
              context.mozImageSmoothingEnabled = false
              context.webkitImageSmoothingEnabled = false
              context.msImageSmoothingEnabled = false
              context.imageSmoothingEnabled = false
              var canvasWidth = canvas.width
              var canvasHeight = canvas.height
              // 调用Canvas2Image插件转图片
              var img = Canvas2Image.Canvas2Image.convertToImage(canvas, canvasWidth, canvasHeight)
              var image = document.createElement('img')
              // 保存到img标签中
              image.src = img.src
              const dataURL = image.src
              var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
              save_link.href = dataURL
              save_link.download = 'test.png'
              var event = document.createEvent('MouseEvents')
              event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
              save_link.dispatchEvent(event)
              image = null
            }
          )
      }
    },
    // 相机飞入
    cameraFlyTo: function (params, cb) {

      // viewer.scene.screenSpaceCameraController.enableInputs = 0;
      var x = params.x || null
      var y = params.y || null
      var z = params.z || null
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(x || 106, y || 35, z || 12000000),
        orientation: {
          heading: Cesium.Math.toRadians(params.heading || 10),
          pitch: Cesium.Math.toRadians(params.pitch || -90),
          roll: Cesium.Math.toRadians(params.roll || -9.5)
        },
        // heading: 0,
        // pitch: -90,
        // roll: -9.5
        duration: 0.1, // 动画持续时间
        complete: () => {
          // viewer.scene.screenSpaceCameraController.enableInputs = 1;
          if (cb) {
            // 飞行完毕后执行的动作
            cb()
          }
        }
      })
    },
    // 文件下载
    downloadElement(url, option = {}) {
      /*
       * 介绍：创建下载链接，下载指定url下的链接
       * 参数说明: url下载链接 类型:String  option下载配置参数 类型：Object
       * 返回值说明: 无返回值
       */
      const dom = document.createElement('a')
      if (Object.keys(option).length) {
        Object.keys(option).forEach((key) => {
          dom[key] = option[key]
        })
      }
      dom.style.display = 'none'
      dom.href = url
      dom.target = '_block'
      document.body.appendChild(dom)
      dom.click()
      document.body.removeChild(dom)
    },
    // 加载多个模型
    handleAddModles(option = {}) {
      // 可以循环调用单个模型函数
      DxCommonUtils.createModel('http://106.12.254.129:39895/data/models3D/modelGltf.gltf', { x: 107, y: 34, z: 60000 })
      // var modelUrlLit = [
      //   // "../../../static/models3D/test.gltf",
      //   // "http://106.12.254.129:39895/data/models3D/d1.gltf",
      //   "http://106.12.254.129:39895/data/models3D/guihua.gltf",
      //   "http://106.12.254.129:39895/data/models3D/house.gltf",
      //   "http://106.12.254.129:39895/data/models3D/mulou.gltf",
      //   "http://106.12.254.129:39895/data/models3D/qiche.gltf",
      // ]
      // modelUrlLit.length && modelUrlLit.forEach((item, index) => {
      //   DxCommonUtils.addPrimitivesAllGltf(item, 0.2 * index)
      // })
    },
    addEntityGltf() {
      var position = Cesium.Cartesian3.fromDegrees(106.0744619, 35.0503706)
      var heading = Cesium.Math.toRadians(45)
      var pitch = 0
      var roll = 0
      var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
      var orientation = Cesium.Transforms.headingPitchRollQuaternion(
        position,
        hpr
      )
      var model_entity = viewer.entities.add({
        name: 'gltf模型23',
        position: position,
        // 默认情况下，模型是直立的并面向东。
        // 通过 Quaternion 为 Entity.orientation 属性指定值来控制模型的方向，控制模型的航向，俯仰和横滚。
        orientation: orientation,
        model: {
          show: true,
          uri: '../../../static/models3D/d1.gltf',
          scale: 2.0, // 缩放比例
          minimumPixelSize: 128, // 最小像素大小
          maximumScale: 20000, // 模型的最大比例尺大小。 minimumPixelSize的上限
          incrementallyLoadTextures: false, // 加载模型后纹理是否可以继续流入
          runAnimations: true, // 是否应启动模型中指定的glTF动画
          clampAnimations: true, // 指定glTF动画是否应在没有关键帧的持续时间内保持最后一个姿势
          // 指定模型是否投射或接收来自光源的阴影 type:ShadowMode
          // DISABLED 对象不投射或接收阴影;ENABLED 对象投射并接收阴影;CAST_ONLY  对象仅投射阴影;RECEIVE_ONLY  对象仅接收阴影
          shadows: Cesium.ShadowMode.ENABLED,
          heightReference: Cesium.HeightReference.NONE
        }
      })
      viewer.flyTo(model_entity)
    },
    addPrimitivesAllGltf(url, dest) {
      var ellipsoid = viewer.scene.globe.ellipsoid
      var position = Cesium.Cartesian3.fromDegrees(106 + dest, 35.0 + dest, 0)
      let p = ellipsoid.cartesianToCartographic(position)
      let promise = Cesium.sampleTerrainMostDetailed(window.viewer.terrainProvider, [p])
      Cesium.when(promise, function () {
        var hpRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(45), 0, 0)
        var fixedFrame = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west')
        var model = viewer.scene.primitives.add(
          Cesium.Model.fromGltf({
            url: url,
            modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(Cesium.Cartographic.toCartesian(p), hpRoll, Cesium.Ellipsoid.WGS84, fixedFrame, position),
            minimumPixelSize: 512,
            maximumScale: 2000,
          })
        )
        model.readyPromise.then(function (model) {
          model.activeAnimations.addAll()
          viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(106, 35.0, 20000) // 相机飞入点
          })
        })
      })
    },
    addPrimitivesGltf(url, positons) {
      viewer.scene.globe.depthTestAgainstTerrain = true; // 开启深度测试
      var ellipsoid = viewer.scene.globe.ellipsoid
      var position = Cesium.Cartesian3.fromDegrees(positons.x, positons.y, positons.z)
      let p = ellipsoid.cartesianToCartographic(position)
      let promise = Cesium.sampleTerrainMostDetailed(window.viewer.terrainProvider, [p])
      Cesium.when(promise, function () {
        var hpRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(45), 0, 0)
        var fixedFrame = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west')
        var model = viewer.scene.primitives.add(
          Cesium.Model.fromGltf({
            url: url,
            modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(Cesium.Cartographic.toCartesian(p), hpRoll, Cesium.Ellipsoid.WGS84, fixedFrame, position),
            minimumPixelSize: 512,
            maximumScale: 2000,
          })
        )
        model.readyPromise.then(function (model) {
          model.activeAnimations.addAll()
          viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(106, 35.0, 20000) // 相机飞入点
          })
        })
      })
    },
    createModel(url, positons) {

      viewer.scene.globe.depthTestAgainstTerrain = true; // 开启深度测试
      viewer.entities.removeAll()
      var position = Cesium.Cartesian3.fromDegrees(
        positons.x,
        positons.y,
        positons.z
      )
      var heading = Cesium.Math.toRadians(45)
      var pitch = 0
      var roll = 0
      var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
      var orientation = Cesium.Transforms.headingPitchRollQuaternion(
        position,
        hpr
      )
      var ent = viewer.entities.add({
        name: url,
        position: position,
        orientation: orientation,
        model: {
          uri: url,
          minimumPixelSize: 4,
          maximumScale: 512,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        }
      })
      DxCommonUtils.cameraFlyTo({
        x: positons.x,
        y: positons.y,
        z: positons.z + 5000.0,
      });
    },
    // cesium切片3dtiles
    add3DTileset(url, positons) {
      viewer.scene.globe.depthTestAgainstTerrain = false;//why
      viewer.scene.logarithmicDepthBuffer = true;//why
      var dayantaTileset = new Cesium.Cesium3DTileset({
        url: url,
        // modelMatrix: m //形状矩阵
      })
      var chengantileset = viewer.scene.primitives.add(dayantaTileset);
      //设置模型的参数！！！
      var newparams = {
        tx: positons.x,  //模型中心X轴坐标（经度，单位：十进制度）
        ty: positons.y, //模型中心Y轴坐标（纬度，单位：十进制度）
        tz: positons.z, //模型中心Z轴坐标（高程，单位：米）
        rx: 0, //X轴（经度）方向旋转角度（单位：度）
        ry: 0, //Y轴（纬度）方向旋转角度（单位：度）
        rz: 2 //Z轴（高程）方向旋转角度（单位：度）
      };
      chengantileset.readyPromise.then(function () {

      }).then(function () {
        if (chengantileset._root.transform == undefined) {
        }
        chengantileset._root.transform = DxCommonUtils.update3dtilesMaxtrix(newparams);
        viewer.zoomTo(chengantileset);
      });


    },
    addThe3DTileset(url, positons) {
      var initialPosition = Cesium.Cartesian3.fromDegrees(
        -74.01881302800248,
        40.69114333714821,
        753
      );
      var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(
        0.27879878293835,
        0.34390550872461,
        0.0716951918898415
      );
      viewer.scene.camera.setView({
        destination: initialPosition,
        orientation: initialOrientation,
        endTransform: Cesium.Matrix4.IDENTITY,
      });

      // Load the NYC buildings tileset
      var tileset = new Cesium.Cesium3DTileset({
        url: Cesium.IonResource.fromAssetId(url.cesiumResource),
      });
      viewer.scene.primitives.add(tileset);
    },
    //  3dtilesv 选择
    update3dtilesMaxtrix(newparams) {
      //旋转
      let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(newparams.rx));
      let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(newparams.ry));
      let mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(newparams.rz));
      let rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
      let rotationY = Cesium.Matrix4.fromRotationTranslation(my);
      let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
      //平移
      let position = Cesium.Cartesian3.fromDegrees(newparams.tx, newparams.ty, newparams.tz);
      let m = Cesium.Transforms.eastNorthUpToFixedFrame(position);

      let scale = Cesium.Matrix4.fromUniformScale(0.101);
      // //缩放
      Cesium.Matrix4.multiply(m, scale, m);
      //旋转、平移矩阵相乘
      Cesium.Matrix4.multiply(m, rotationX, m);
      Cesium.Matrix4.multiply(m, rotationY, m);
      Cesium.Matrix4.multiply(m, rotationZ, m);
      //赋值给tileset
      return m;
    },
    // 笛卡尔 经纬度
    cartesianTOlongAndlat(point) {
      // 将笛卡尔坐标转化为弧度坐标
      var cartographic = Cesium.Cartographic.fromCartesian(point)
      // 将弧度坐标转换为经纬度坐标
      var longitude = Cesium.Math.toDegrees(cartographic.longitude) // 经度
      var latitude = Cesium.Math.toDegrees(cartographic.latitude) // 纬度
      var height = cartographic.height // 高度
      return {
        x: longitude, y: latitude, z: height
      }
    },
    // 绘制墙体
    addWell(positons) {
      viewer.entities.removeAll();
      //地质开挖不能有深度测试，有深度测试会被遮盖
      viewer.scene.globe.depthTestAgainstTerrain = false;
      // var globe = viewer.scene.globe;
      // globe.showGroundAtmosphere = true;
      // globe.translucency.enabled = true;
      // // globe.translucency.frontFaceAlpha = 0.9;
      // Cesium.Math.clamp(0.3, 0.0, 1.0);

      // viewer.entities.add({
      //   name: "Red wall at height",
      //   wall: {
      //     positions: Cesium.Cartesian3.fromDegreesArrayHeights(positons),
      //     // minimumHeights: [100.0, 100.0],
      //     material: Cesium.Color.RED,
      //   },
      // });

      //设置地图basecolor为透明色
      // viewer.scene.globe.baseColor = new Cesium.Color(1, 1, 1, 1.0);
      // //循环设置影像的透明度
      // var _mapAlpha = 0.2;
      // if (viewer.imageryLayers) {
      //   for (var i = 0; i < viewer.imageryLayers.length; i++) {
      //     viewer.imageryLayers.get(i).alpha = _mapAlpha;
      //   }
      // }
      //刷新全部的影像切片
      // viewer.scene.globe._surface.invalidateAllTiles();
      // viewer.scene.skyAtmosphere.show = false;


      viewer.entities.add({
        name: "Blue extruded corridor with beveled corners and outline",
        corridor: {
          positions: Cesium.Cartesian3.fromDegreesArray(positons),
          // height: 1000.0,
          extrudedHeight: -2000.0,
          width: 2.0,
          cornerType: Cesium.CornerType.BEVELED,
          material: Cesium.Color.BLUE.withAlpha(0.4),
          // outline: true,
          // outlineColor: Cesium.Color.BLUE,
        },
      });



      viewer.zoomTo(viewer.entities);

    },
    // 删除全部entities.removeAll
    removeAllEntities() {
      // viewer.entities.removeAll();
      // viewer.dataSources.removeAll();
    },
    // 获取文件路径后缀
    getSuffixType(file) {
      if (typeof (file) == 'string') {
        var filename = file;
        var index1 = filename.lastIndexOf(".");
        var index2 = filename.length;
        var type = filename.substring(index1, index2);
        return type;
      } else {
        return 'cesiumtiles'
      }

    }
  }

  return DxCommonUtils
}
// eslint-disable-next-line eol-last
export default dxCommonFun()